#include "object_descriptor.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// #include "util/hex_util.h"

#define printf(fmt, ...) //fprintf(stdout, fmt, ##__VA_ARGS__)

// 对象结构释放
int object_free(const char *name, void *obj, void *obj_desc_ptr, int32_t obj_field_count) {
    int ret = 0;
    for (int i=0;i<obj_field_count;i++)
    {
        st_obj_desc_t *info = obj_desc_ptr+i*(sizeof(st_obj_desc_t));
        void *ptr = obj+ info->offset;
        printf("%s:%d name=%s info->offset=%d info->size=%llu\n", __func__, __LINE__, info->name, info->offset, info->size);
        if (info->type >= E_OFT_END || info->type <= E_OFT_NONE)
        {
            continue;
        }
        else if (info->type == E_OFT_ARR_HEAP || info->type == E_OFT_ARR_STACK)
        {
            int count = 0;
            if (info->type == E_OFT_ARR_STACK) {
                if (info->msize == 0) {
                    continue;
                }
                count = info->size / info->msize;
            }else {
                for (int j=0;j<obj_field_count;j++) {
                    st_obj_desc_t *sub_info = obj_desc_ptr+j*(sizeof(st_obj_desc_t));
                    if (info->noffset == sub_info->offset) {
                        if (sub_info->size == 1) {
                            count = *(uint8_t*)(obj + sub_info->offset);
                        } else if (sub_info->size == 2) {
                            count = *(uint16_t*)(obj + sub_info->offset);
                        } else if (sub_info->size == 4) {
                            count = *(uint32_t*)(obj + sub_info->offset);
                        } else if (sub_info->size == 8) {
                            count = *(uint64_t*)(obj + sub_info->offset);
                        }
                        break;
                    }
                    sub_info = NULL;
                }
            }

            if (count == 0) {
                printf("%s:%d name=%s not found info->noffset=%d\n", __func__, __LINE__, info->name, info->noffset);
                continue;
            }

            printf("%s:%d name=%s count=%d\n", __func__, __LINE__, info->name, count);
            void *heap_ptr = NULL;
            if (info->type == E_OFT_ARR_HEAP) {
               heap_ptr = *(void **)ptr;
            }
            for (int j=0;j<count;j++) {
                void *sub_obj = NULL;
                if (info->type == E_OFT_ARR_STACK) {
                    sub_obj = ptr + j * info->msize;
                }else {
                    if ((*(void **)ptr) == NULL) {
                        continue;
                    }
                    sub_obj = ((*(void **)ptr)) + j * info->msize;
                }
                if (info->mtype == E_OFT_STRUCT) {
                   object_free(info->name, sub_obj, info->info_ptr, info->info_field_size);
                }
    
            }
            if (heap_ptr != NULL) {
                free(heap_ptr);
            }
        } 
        else if (info->type == E_OFT_STRUCT)
        {
            object_free(info->name, obj + info->offset,info->info_ptr, info->info_field_size);  
        }
    }
    return 0;
}